package com.quanyan.handler;

import com.quanyan.common.GlobalConstValue;
import com.quanyan.entity.Command;
import com.quanyan.util.CommUtil;
import com.quanyan.util.StringEncode;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;

public class CommandDecoder extends FrameDecoder {
    @Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
        throws Exception {
        
        if (buf.readableBytes() < GlobalConstValue.FRM_BASIC_LENGTH) {
            return null;
        }
       //防止socket字节流攻击
        if(buf.readableBytes()>10240){
            buf.skipBytes(buf.readableBytes());
        }
        //记录包头开始的index
        String head;
        int beginReader;
        while(true){

            beginReader=buf.readerIndex();
            buf.markReaderIndex();
            // 解析命令头
            byte[] headBytes = new byte[GlobalConstValue.FRM_HEAD_LENGTH];
            buf.readBytes(headBytes);
            head=new String(headBytes, StringEncode.UTF8.getEncoder());

            if(head!=null&&head.equals(GlobalConstValue.HEAD)){
                break;
            }
            //未读到包头，略过一个字节
            buf.resetReaderIndex();
            buf.readByte();

            //长度变得不满足
            if(buf.readableBytes()<GlobalConstValue.FRM_BASIC_LENGTH){
                return null;
            }
        }

       // 解析CMD 命令格式
        String cmd= CommUtil.getStringFieldN(buf, StringEncode.UTF8);

        int dataLen = buf.readInt();
       //判断请求数据包数据是否到齐
        if(buf.readableBytes()<dataLen){
            //还原指针
            buf.readerIndex(beginReader);
            return null;
        }
        //读data数据
        byte[] data=new byte[dataLen];
        buf.readBytes(data);
        String dataStr=new String(data,StringEncode.UTF8.getEncoder());

       Command command = new Command();
        
        command.setHead(head);
        command.setCmd(cmd);
        command.setData(dataStr);

        
        return command;
    }
}
